package bluetooth;

import java.io.IOException;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;

/**
 * @author pmp
 */

public class Server implements BtListener
{
	private String UUID;
    private StreamConnectionNotifier notifier;
    private Thread listener;
    private ServerListener serverListener;
    private BtVector btConnection;
    private LocalDevice device;

    public void createServer(ServerListener _serverListener)
    {
		try
        {
            UUID = new UUID("1101", true).toString();
            btConnection=new BtVector();
            serverListener=_serverListener;
			device = LocalDevice.getLocalDevice();
			device.setDiscoverable(DiscoveryAgent.GIAC);
			String url = "btspp://localhost:" + UUID + ";name=BtTank";
			log("Create server:\n" + url+"\n");
			notifier = (StreamConnectionNotifier) Connector.open(url);
		}
        catch (BluetoothStateException e)
        {
			log(e);
		}
        catch (IOException e)
        {
			log(e);
		}
    }

    public void publishServer()
    {
        listener = new Thread()
        {
            public void run()
            {
                try
                {
                    while (true)
                    {
                        log("Waiting for connection...");
                        addBtConnection(notifier.acceptAndOpen());
                    }
                }
                catch (IOException e)
                {
                    log(e);
                }
			}
		};
		listener.start();
    }

    public void sendData(String data, String btAdress)
    {
        try
        {
            ((BtConnection)btConnection.get(findDevice(btAdress))).sendData(data);
        }
        catch(IndexOutOfBoundsException ex)
        {
            log(ex);
        }
    }

    private int findDevice(String btAdress)
    {
        for (int i = 0; i < btConnection.size(); i++)
        {
            if(((BtConnection)btConnection.get(i)).getBtAdress()==btAdress)
            {
                return i;
            }
        }
        return -1;
    }

    public void stopPublishingServer()
    {
        try 
        {
            notifier.close();
            listener=null;
            log("Server listener down.");
        }
        catch (IOException ex)
        {
            log(ex);
        }
    }

	private void addBtConnection(StreamConnection conn)
    {
        btConnection.add(new BtConnection(conn, this));
        serverListener.clientConnected(((BtConnection)btConnection.get(btConnection.size()-1)).getBtAdress());
	}

    public void connectionLost(String btAdress)
    {
        btConnection.remove(findDevice(btAdress));
        serverListener.connectionLost(btAdress);
    }

    public void dataReceived(String data, String btAdress)
    {
        serverListener.dataReceived(data, btAdress);
    }

	private void log(String msg)
    {
		System.out.println(msg);
	}

	private void log(Throwable e)
    {
		log(e.getMessage());
	}
}
